<?php

namespace App\Library\Guanyuan;

use Guanguans\Notify\Factory;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\HandlerStack;
use GuzzleRetry\GuzzleRetryMiddleware;
use Illuminate\Support\Facades\Log;
use Kuafu\GeneralFs\BuildFs;

class GuanyuanTool
{
    /**
     * 获取观远数据原始记录表
     * @param string $source 例如：s580b6c8918224fdfa8da24b，https://kuafu.guandatacloud.com/data-source/s580b6c8918224fdfa8da24b/details/overview
     * @param string $token 例如：i99f447954eda4fbxxxxxxxx，夏目同学可以生成token
     * @param array $filters https://thoughts.teambition.com/sharespace/616fb6829cdb8400410e91ac/docs/6328547cfdd87e0041cd3fb4
     * @return array
     * @throws GuzzleException
     */
    public static function fetch(
        string $source,
        string $token,
        array $filters = [],
        int $timeout = 8,
        array $field = []
    ): array {
        $url = "https://kuafu.guandatacloud.com/public-api/data-source/{$source}/token/{$token}";
        $num = 1;

        // 重试事件
        $sendFeishuRobot = function() use ($url, $token, &$num) {
            try {
                // 获取调用路径
                $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);

                foreach ($backtrace as $key => $item) {
                    if ((isset($item['file']) && strpos($item['file'], 'vendor') !== false) || (isset($item['class']) && strpos($item['class'], 'Illuminate') !== false)) {
                        unset($backtrace[$key]);
                    }
                }

                $attach = '(' . ($num++) . ')';

                // 获得消息内容
                $cardJson = self::getFeishuCardJson(str_replace($token, '*******', $url), $backtrace, $attach);

                // 发送飞书消息
                BuildFs::newRobot(0, BuildFs::MSG_TYPE_CARD)
                    ->setRobotConfig('https://open.feishu.cn/open-apis/bot/v2/hook/88e66bc8-e079-499c-8e06-210fb9210e96', 'k5dcnKaVUVe9gXBWKjlXpc')
                    ->setCardContent(json_decode($cardJson, true))
                    ->send();

            } catch (\Exception $exception) {}
        };

        // 添加重试机制
        $stack = HandlerStack::create();
        $stack->push(GuzzleRetryMiddleware::factory());
        $response = (new Client([
            'http_errors'        => false,
            'handler'            => $stack,
            'retry_on_timeout'   => true,
            'max_retry_attempts' => 3,
            'on_retry_callback'  => $sendFeishuRobot
        ]))->post($url, ['json' => ['filters' => $filters], 'timeout' => $timeout]);
        $body     = $response->getBody()->getContents();
        $arr      = json_decode($body, true);

        //添加日志
//        Log::channel('guanyuanApi')->info("{$url}\nfilters:" . json_encode($filters,
//                JSON_UNESCAPED_UNICODE) . "\nhttpCode:{$response->getStatusCode()}\nbody:{$body}");

        $data = static::formatList($arr);
        if (!empty($field)) {
            $data = array_map(function ($item) use ($field) {
                $filteredItem = [];
                foreach ($field as $oldKey => $newKey) {
                    if (isset($item[$oldKey])) {
                        $filteredItem[$newKey] = $item[$oldKey];
                    }
                }
                return $filteredItem;
            }, $data);
        }
        return $data;
    }

    /**
     * 格式化观远数据
     * @param array $arr
     * @return array
     */
    public static function formatList(array $arr): array
    {
        $columns       = $arr['response']['columns'] ?? [];
        $list          = $arr['response']['data'] ?? [];
        $formattedList = [];
        foreach ($list as $item) {
            $newItem = [];
            foreach ($item as $k => $v) {
                $newK           = $columns[$k];
                $newItem[$newK] = $v;
            }
            $formattedList[] = $newItem;
        }
        return $formattedList;
    }


    /**
     * 组建消息
     * @param string $url
     * @param array $functionPath
     * @param string $attach
     * @return false|string
     */
    public static function getFeishuCardJson(string $url, array $functionPath, string $attach = '')
    {
        $cardJson = vsprintf(file_get_contents(resource_path('Guanyuan/timeoutNotification.json')), [$url, $attach]);

        $cardArr = json_decode($cardJson, true);

        $elements = [];

        foreach ($functionPath as $item) {
            $className    = basename($item['class'] ?? '-');
            $line         = $item['line'] ?? 0;
            $functionName = $item['function'] ?? '-';
            $elements[] = [
                'tag'       => 'column_set',
                'flex_mode' => 'none',
                'columns'   => [
                    [
                        'tag'            => 'column',
                        'width'          => 'weighted',
                        'weight'         => 1,
                        'vertical_align' => 'top',
                        'elements'       => [
                            [
                                'tag'        => 'markdown',
                                'content'    => $className,
                                'text_align' => 'center',
                            ]
                        ],
                    ],
                    [
                        'tag'            => 'column',
                        'width'          => 'weighted',
                        'weight'         => 1,
                        'vertical_align' => 'top',
                        'elements'       => [
                            [
                                'tag'        => 'markdown',
                                'content'    => (string)$line,
                                'text_align' => 'center',
                            ]
                        ],
                    ],
                    [
                        'tag'            => 'column',
                        'width'          => 'weighted',
                        'weight'         => 1,
                        'vertical_align' => 'top',
                        'elements'       => [
                            [
                                'tag'        => 'markdown',
                                'content'    => $functionName,
                                'text_align' => 'center',
                            ]
                        ],
                    ]
                ],
            ];
        }

        $cardArr['elements'] = array_merge($cardArr['elements'], $elements);

        return json_encode($cardArr, JSON_UNESCAPED_UNICODE);
    }
}
